# -*- coding: utf-8 -*-
#
# @Author: CPS
# @email: 373704015@qq.com
# @Date: 2021-09-28 18:27:27.431387
# @Last Modified by: CPS
# @Last Modified time: 2021-09-28 18:27:27.431387
# @file_path "D:\CPS\MyProject\gis\learn"
# @Filename "auto_table.py"
# @Description: 功能描述
#

import sys
import os

import arcpy
reload(sys)
sys.setdefaultencoding('utf8')

class Table(object):
    def __init__(self, element_name="", mxd_name=""):
        self.table_element_name = str(element_name)
        self.text_element_name = str(element_name)
        self.target = mxd_name

        self.mxd = object()
        self.table = object()
        self.text = object()

        self.table_w = 0
        self.table_h = 0
        self.table_x = 0
        self.table_y = 0

        self.xy = []
        self.data = []
        self.shape = None

        self.init()

    def init(self):
        self.mxd = arcpy.mapping.MapDocument(self.target or r"current")
        self.table = arcpy.mapping.ListLayoutElements(self.mxd, "GRAPHIC_ELEMENT", self.table_element_name)[0]
        self.text = arcpy.mapping.ListLayoutElements(self.mxd, "TEXT_ELEMENT", self.text_element_name)[0]

        self.table_w = self.table.elementWidth
        self.table_h = self.table.elementHeight

        self.table_x = self.table.elementPositionX
        self.table_y = self.table.elementPositionY

        self.clean()

        return self

    def draw_rows(self, data, max_height):
        self.xy = []
        row_num = len(data)

        row_h = self.table_h / row_num

        if not max_height: max_height = self.table_h / row_num

        if row_h > max_height: row_h = max_height

        y = self.table_h - row_h + self.table_y

        for i in range(0, len(data)):
            each_row = data[i]

            x = self.table_x
            xy = []
            col_num = len(each_row)
            col_base_w = self.table_w / col_num

            for each_col in each_row:
                col = self.table.clone("_col")

                col.elementPositionX = x
                col.elementPositionY = y
                col.elementWidth = col_base_w
                col.elementHeight = row_h

                xy.append({"x":x, "y":y, "w":col_base_w, "h":row_h})
                x += col_base_w

            self.xy.append(xy)
            y -= row_h

    def draw_data(self, data, font_size, align_center=True):
        padding = 4

        for i in range(0, len(data)):
            row = data[i]

            for j in range(0, len(row)):
                new_text = self.text.clone("_text")
                new_text.text = data[i][j]
                new_text.fontSize = font_size
                new_text.elementPositionY = self.xy[i][j]["y"] + (self.xy[i][j]["h"] / 2 - new_text.elementHeight / 2)

                if align_center:
                    new_text.elementPositionX = self.xy[i][j]["x"] + self.xy[i][j]["w"] / 2 - new_text.elementWidth / 2
                else:
                    new_text.elementPositionX = self.xy[i][j]["x"] + padding

    def get_data(self, layer_name, title, fields, sort_field=""):
        shape = self.mxd.dataDrivenPages.pageRow.shape

        search_field = fields[:]
        if sort_field: search_field.append(sort_field)

        data_body = []
        with arcpy.da.SearchCursor(layer_name, ['SHAPE@'] + search_field) as rows:
            for row in rows:
                if shape.contains(row[0]):
                    data_body.append([row[i] for i in range(1, len(search_field) + 1 )])

        if sort_field:
            data_body = sorted(data_body, key=(lambda x:[x[len(search_field) - 1]]))
            data_body = [each[:-1] for each in data_body]

        self.data = [ [title], fields ] + data_body

        return self

    def draw(self, font_size=30, max_height=0, data=None):
        if not data : data = self.data

        self.init()
        self.clean()
        self.draw_rows(data, max_height)
        self.draw_data(data, font_size)

        return self

    def clean(self):
        if not hasattr(self.mxd, 'title'): return self

        for elm in arcpy.mapping.ListLayoutElements(self.mxd, wildcard='*'+self.table_element_name+"_col*"):
            elm.delete()

        for elm in arcpy.mapping.ListLayoutElements(self.mxd, wildcard='*'+self.text_element_name+"_text*"):
            elm.delete()
        return self

def mxd_export(mxd, ext, output, resolution=300):
    arcpy.AddMessage(r'success ! output: ' + output)

    if ext == 'png':
        arcpy.mapping.ExportToPNG(mxd, output, resolution=resolution)

    elif ext == 'jpg' or ext =='jpeg':
        arcpy.mapping.ExportToPNG(mxd, output, resolution=resolution)

    elif ext == 'pdf':
        arcpy.mapping.ExportToPDF(mxd, output, resolution=resolution)

    else:
        mxd.saveACopy(output)




def mxd_export_thumb(mxd, output):
    arcpy.mapping.ExportToJPEG(mxd, output, jpeg_quality=70, resolution=72)

def get_title(tar):
    return [arcpy.GetParameterAsText(each) for each in tar]

def get_layers(tar):
    return [arcpy.GetParameter(each) for each in tar]

def get_fields(tar):
    return [arcpy.GetParameterAsText(each).split(u';') for each in tar]

def get_sort_field(tar):
    return [arcpy.GetParameterAsText(each) for each in tar]

def get_export(tar):
    return arcpy.GetParameterAsText(tar).lower()

def get_export_ext(tar):
    return arcpy.GetParameterAsText(tar)

def get_export_dir(tar):
    return arcpy.GetParameterAsText(tar)

def get_export_thumb(tar):
    return arcpy.GetParameterAsText(tar).lower()

def get_index_start(tar):
    return int(arcpy.GetParameterAsText(tar))

def get_index_end(tar):
    return int(arcpy.GetParameterAsText(tar))

def get_font_size(tar):
    return int(arcpy.GetParameterAsText(tar))


def draw_data_table():
    # set params index
    data_layer_list = get_layers([0, 4])
    table_title_list = get_title([1, 5])
    field_list = get_fields([2, 6])
    sort_field_list = get_sort_field([3, 7])
    font_size = get_font_size(8) or 10

    table_list = []
    for i in range(0,len(data_layer_list)):
        data_layer = data_layer_list[i]

        if not data_layer or not hasattr(data_layer, 'name'): continue

        # get each params
        title = table_title_list[i] or data_layer.name
        fields = field_list[i]
        sort_field = sort_field_list[i]

        # build the bable
        each_table = Table(title).get_data(data_layer.name, title, fields, sort_field).draw(font_size)

        table_list.append(each_table)
    return table_list

def main():
    mxd = arcpy.mapping.MapDocument(r'current')

    index_start = get_index_start(10)
    index_end = get_index_start(11) or mxd.dataDrivenPages.pageCount
    export_thumb = get_export_thumb(12)
    export_ext = get_export_ext(13)
    export_dir = get_export_dir(14)

    dir_name = os.path.dirname(export_dir)
    file_name = os.path.basename(export_dir)

    if file_name.find('.') == -1:
        name = file_name
    else:
        name = file_name.split('.')[0]

    arcpy.SetProgressor('step', 'cps', index_start, index_end + 1, 1)
    for pageNum in range(index_start, index_end + 1):
        mxd.dataDrivenPages.currentPageID = pageNum

        output_name = dir_name + os.path.sep + u'{name}_{pageNum}.{ext}'.format(name=name, pageNum=pageNum, ext=export_ext)
        output_thumb_name = dir_name + os.path.sep + u'{name}_{pageNum}_thumb.{ext}'.format(name=name, pageNum=pageNum, ext=export_ext)

        arcpy.SetProgressorLabel("Outputint...>>> {0}".format(output_name))

        draw_data_table()

        mxd_export(mxd, export_ext, output_name)

        if export_thumb == 'true':  mxd_export_thumb(mxd, output_thumb_name)

        arcpy.SetProgressorPosition()

    arcpy.ResetProgressor()


if ( __name__ == "__main__"):
    arcpy.env.overwriteOutput = True

    is_export = get_export(9)
    if is_export == 'true':
        main()
    else:
        draw_data_table()

arcpy.AddMessage(u'workspace: ' + str(arcpy.env.workspace))
# arcpy.AddMessage(u'coordinate: ' + coordinate)
